{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d558f4d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from mindquantum.core.gates import X, H, Z, RX, RY, RZ, CNOT\n",
    "from mindquantum.core.gates import Measure\n",
    "from mindquantum.core.circuit import Circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1697a969",
   "metadata": {},
   "source": [
    "## 模块化设计量子线路"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d0db7ddf",
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_EPR_state(p: int, q: int) -> Circuit:\n",
    "    \"\"\"制备EPR Pair\n",
    "    Args:\n",
    "        p: 贝尔态作用第1个位置\n",
    "        q: 贝尔态作用第2个位置\n",
    "    Return:\n",
    "        制备贝尔态线路\n",
    "    \"\"\"\n",
    "    return Circuit([\n",
    "        H(p),\n",
    "        X(q, p)\n",
    "    ])\n",
    "\n",
    "def create_random_state(p: int) -> Circuit:\n",
    "    \"\"\"在1个比特上制备随机态，通过随机旋转初态制备\n",
    "    Args:\n",
    "        p: 随机值作用比特\n",
    "    Return:\n",
    "        处于随机的单量子态\n",
    "    \"\"\"\n",
    "    # 使用RX, RY, RZ随机旋转角度作用在 |0> 上实现随机状态制备\n",
    "    t1, t2, t3 = 2 * np.pi * np.random.random(size=3)\n",
    "    return Circuit([\n",
    "        RX(t1).on(p), # 不使用函数 on() 直接使用 RX(t1)(p) 也可\n",
    "        RY(t2).on(p),\n",
    "        RZ(t3).on(p)\n",
    "    ])\n",
    "\n",
    "def create_basic_module(p: int, q: int) -> Circuit:\n",
    "    \"\"\"CNOT,H,Measure 的组合在本位量子通信经常用到，综合为一个接口\n",
    "    Args:\n",
    "        p: 第1个量子位置\n",
    "        q: 第2个量子位置\n",
    "    Return:\n",
    "        量子线路模块\n",
    "    \"\"\"\n",
    "    return Circuit([\n",
    "        CNOT(q, p),\n",
    "        H(p),\n",
    "        Measure(f'q{p}').on(p),\n",
    "        Measure(f'q{q}').on(q)\n",
    "    ])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "07b6c529",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_measure_result(ket_str: str, idx: int or list) -> int or list:\n",
    "    \"\"\"获取指定状态的测量结果，通过解析 get_qs(ket=True) 的返回值实现\n",
    "    Args:\n",
    "        ket_str: get_qs(ket=True)获取的量子态\n",
    "        idx: 需要获取的量子位\n",
    "    Return:\n",
    "        指定量子位的测量结果，\n",
    "    \"\"\"\n",
    "    ket_str2 = ket_str.split('\\n')[0]\n",
    "    if isinstance(idx, int):\n",
    "        new_idx = -idx - 2\n",
    "        return ket_str2[new_idx]\n",
    "    if isinstance(idx, list):\n",
    "        return [ket_str2[-i-2] for i in idx]\n",
    "    print(\"Error: idx should be int or list!\")\n",
    "    return -1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02ae2213",
   "metadata": {},
   "source": [
    "## 论文线路复现"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c265447f",
   "metadata": {},
   "source": [
    "### 案例1\n",
    "\n",
    "- Fig.3 量子瞬时传输线路\n",
    "\n",
    "<img src=\"images/fig3.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0f839567",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fig.3\n",
      "complete circuit:\n",
      "q0: ──RX(0.102)────RY(2.666)────RZ(2.838)────●──────H──────M(q0)──\n",
      "                                             │\n",
      "q1: ──────H────────────●─────────────────────X────M(q1)───────────\n",
      "                       │\n",
      "q2: ───────────────────X──────────────────────────────────────────\n",
      "\n",
      "Measure result:\n",
      "q0=0, q1=0\n",
      "\n",
      "Send state ¦qn,...,q0⟩:\n",
      "(0.08477243949860924-0.2249188354701979j)¦0⟩\n",
      "(0.15888531027657884+0.9575910448257648j)¦1⟩\n",
      "\n",
      "Recv state ¦qn,...,q0⟩:\n",
      "(0.08477243949860924-0.2249188354701979j)¦000⟩\n",
      "(0.15888531027657884+0.9575910448257648j)¦100⟩\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def simulate_fig3():\n",
    "    \"\"\"复现论文 Fig3 的线路，实现 EPR 传输\n",
    "    \"\"\"\n",
    "    cir_send = create_random_state(0)      # 初始需要传输的态，对应论文中 |y>\n",
    "    cir_epr12 = create_EPR_state(1, 2)    # 制备 EPR\n",
    "    cir_mod01 = create_basic_module(0, 1)  # 线路\n",
    "\n",
    "    # 使用同一个随机数种子，避免各次测量结果不同\n",
    "    seed = np.random.randint(0, 0xff)            # 随机数种子\n",
    "    cir_all = cir_send + cir_epr12 + cir_mod01  # 量子线路\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q0, q1测量结果，保存在c0, c1\n",
    "    c0, c1 = get_measure_result(ket_str, [0, 1])\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    if c1 == '1':\n",
    "        cir_all += X(2)\n",
    "    if c0 == '1':\n",
    "        cir_all += Z(2)\n",
    "\n",
    "    send_state = cir_send.get_qs(ket=True, seed=seed)\n",
    "    recv_state = cir_all.get_qs(ket=True, seed=seed)\n",
    "\n",
    "    print(f'Fig.3\\ncomplete circuit:\\n{cir_all}\\n')\n",
    "    print(f'Measure result:\\nq0={c0}, q1={c1}\\n')\n",
    "    print(f'Send state ¦qn,...,q0⟩:\\n{send_state}\\n')\n",
    "    print(f'Recv state ¦qn,...,q0⟩:\\n{recv_state}\\n')\n",
    "\n",
    "\n",
    "simulate_fig3()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "169d0f99",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "### 案例2\n",
    "\n",
    "- Fig.5 量子中间方案线路\n",
    "\n",
    "<img src=\"images/fig5.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "3b68acfe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fig.5\n",
      "complete circuit:\n",
      "q0: ──RX(1.476)────RY(5.212)────RZ(2.025)────●──────H──────M(q0)───────────\n",
      "                                             │\n",
      "q1: ──────H────────────●─────────────────────X────M(q1)────────────────────\n",
      "                       │\n",
      "q2: ───────────────────X────────────X────────Z──────●────────H──────M(q2)──\n",
      "                                                    │\n",
      "q3: ──────H────────────●────────────────────────────X──────M(q3)───────────\n",
      "                       │\n",
      "q4: ───────────────────X────────────X──────────────────────────────────────\n",
      "\n",
      "measure result:\n",
      "q0 = 1, q1 = 1\n",
      "\n",
      "send state ¦qn,...,q0⟩:\n",
      "(-0.04553208008366766+0.7214669282630273j)¦0⟩\n",
      "(-0.29093413911875327+0.6267133537760277j)¦1⟩\n",
      "\n",
      "recv state ¦qn,...,q0⟩:\n",
      "(-0.04553208008366766+0.7214669282630272j)¦01011⟩\n",
      "(-0.2909341391187532+0.6267133537760277j)¦11011⟩\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def simulate_fig5():\n",
    "    \"\"\"复现 Fig.5 线路\"\"\"\n",
    "    cir_send = create_random_state(0)     # the send state |y>\n",
    "    cir_epr1 = create_EPR_state(1, 2)     # EPR Pair [A2, C1]\n",
    "    cir_epr2 = create_EPR_state(3, 4)     # EPR Pair [C2, B]\n",
    "    cir_mod01 = create_basic_module(0, 1)\n",
    "    cir_mod23 = create_basic_module(2, 3)\n",
    "\n",
    "    cir_all = cir_send + cir_epr1 + cir_epr2 + cir_mod01\n",
    "\n",
    "    # 使用同一个随机数种子，避免各次测量结果不同\n",
    "    seed = np.random.randint(0, 0xff)\n",
    "\n",
    "    ## 第一次测量\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q0, q1测量结果，保存在c0, c1\n",
    "    c0, c1 = get_measure_result(ket_str, [0, 1])\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    if c1 == '1':\n",
    "        cir_all += X(2)\n",
    "    if c0 == '1':\n",
    "        cir_all += Z(2)\n",
    "\n",
    "    ## 第二次测量\n",
    "    cir_all += cir_mod23 # 加上第2部分测量\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q2, q3测量结果，保存在c2, c3\n",
    "    c2, c3 = get_measure_result(ket_str, [2, 3])\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    if c3 == '1':\n",
    "        cir_all += X(4)\n",
    "    if c2 == '1':\n",
    "        cir_all += Z(4)\n",
    "\n",
    "    print(f'Fig.5\\ncomplete circuit:\\n{cir_all}\\n')\n",
    "    print(f'measure result:\\nq0 = {c0}, q1 = {c1}\\n')\n",
    "    print(f'send state ¦qn,...,q0⟩:\\n{cir_send.get_qs(ket=True, seed=seed)}\\n')\n",
    "    print(f'recv state ¦qn,...,q0⟩:\\n{cir_all.get_qs(ket=True, seed=seed)}\\n')\n",
    "\n",
    "\n",
    "simulate_fig5()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "55226037",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "### 案例3\n",
    "\n",
    "- Fig.6 在源节点和宿节点之间通过一个中间节点节点共享EPR对\n",
    "\n",
    "<img src=\"images/fig6.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9f8e6a73",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fig.6\n",
      "complete circuit:\n",
      "q0: ──H────●─────────────────────────\n",
      "           │\n",
      "q1: ───────X────●──────H──────M(q1)──\n",
      "                │\n",
      "q2: ──H────●────X────M(q2)───────────\n",
      "           │\n",
      "q3: ───────X─────────────────────────\n",
      "\n",
      "measure result:\n",
      "q1 = 0, q2 = 0\n",
      "\n",
      "recv state ¦qn,...,q0⟩:\n",
      "√2/2¦0000⟩\n",
      "√2/2¦1001⟩\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def simulate_fig6():\n",
    "    cir_epr1 = create_EPR_state(0, 1) # EPR Pair [A, C1]\n",
    "    cir_epr2 = create_EPR_state(2, 3) # EPR Pair [C2, B]\n",
    "    cir_mod12 = create_basic_module(1, 2)\n",
    "    cir_all = cir_epr1 + cir_epr2 + cir_mod12\n",
    "\n",
    "    # 使用同一个随机数种子，避免各次测量结果不同\n",
    "    seed = np.random.randint(0, 0xff) # 随机数种子\n",
    "\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q0, q1测量结果，保存在c0, c1\n",
    "    c1, c2 = get_measure_result(ket_str, [1, 2])\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    if c2 == '1':\n",
    "        cir_all += X(3)\n",
    "    if c1 == '1':\n",
    "        cir_all += Z(3)\n",
    "\n",
    "    print(f'Fig.6\\ncomplete circuit:\\n{cir_all}\\n')\n",
    "    print(f'measure result:\\nq1 = {c1}, q2 = {c2}\\n')\n",
    "    print(f'recv state ¦qn,...,q0⟩:\\n{cir_all.get_qs(ket=True, seed=seed)}\\n')\n",
    "\n",
    "simulate_fig6()\n",
    "# |0xx0> + |1xx1>"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "670bbcec",
   "metadata": {},
   "source": [
    "### 案例4\n",
    "\n",
    "- Fig.8 使用EPR桥接传输单个量子态\n",
    "\n",
    "<img src=\"images/fig8.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9d64838d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fig.8\n",
      "complete circuit:\n",
      "q0: ──RX(4.185)────RY(4.812)────RZ(4.866)──────●────────H──────M(q0)──\n",
      "                                               │\n",
      "q1: ──────H────────────●───────────────────────X──────M(q1)───────────\n",
      "                       │\n",
      "q2: ───────────────────X────────────●──────────H──────M(q2)───────────\n",
      "                                    │\n",
      "q3: ──────H────────────●────────────X────────M(q3)────────────────────\n",
      "                       │\n",
      "q4: ───────────────────X────────────X──────────Z────────Z─────────────\n",
      "\n",
      "measure result:\n",
      "q3=1, q2=1, q1=0, q0=1\n",
      "\n",
      "send state ¦qn,...,q0⟩:\n",
      "(0.09804527980305622-0.6822699336681646j)¦0⟩\n",
      "(-0.16412155535637818-0.7056620832864566j)¦1⟩\n",
      "\n",
      "recv state ¦qn,...,q0⟩:\n",
      "(0.0980452798030562-0.6822699336681646j)¦01101⟩\n",
      "(-0.1641215553563781-0.7056620832864566j)¦11101⟩\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def simulate_fig8():\n",
    "    cir_send = create_random_state(0)\n",
    "    cir_epr12 = create_EPR_state(1, 2)\n",
    "    cir_epr34 = create_EPR_state(3, 4)\n",
    "    cir_mod23 = create_basic_module(2, 3)\n",
    "    cir_mod01 = create_basic_module(0, 1)\n",
    "\n",
    "    cir_all = cir_send + cir_epr12 + cir_epr34 + cir_mod23\n",
    "\n",
    "    # 使用同一个随机数种子，避免各次测量结果不同\n",
    "    seed = np.random.randint(0, 0xff)\n",
    "\n",
    "    ## 第一次测量\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q2, q3测量结果，保存在c2, c3\n",
    "    c2, c3 = get_measure_result(ket_str, [2, 3])\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    if c3 == '1':\n",
    "        cir_all += X(4)\n",
    "    if c2 == '1':\n",
    "        cir_all += Z(4)\n",
    "\n",
    "    ## 第二次测量\n",
    "    cir_all += cir_mod01 # 加上第2部分测量\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q0, q2测量结果，保存在c0, c1\n",
    "    c0, c1 = get_measure_result(ket_str, [0, 1])\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    if c1 == '1':\n",
    "        cir_all += X(4)\n",
    "    if c0 == '1':\n",
    "        cir_all += Z(4)\n",
    "\n",
    "    print(f'Fig.8\\ncomplete circuit:\\n{cir_all}\\n')\n",
    "    print(f'measure result:\\nq3={c3}, q2={c2}, q1={c1}, q0={c0}\\n')\n",
    "    print(f'send state ¦qn,...,q0⟩:\\n{cir_send.get_qs(ket=True, seed=seed)}\\n')\n",
    "    print(f'recv state ¦qn,...,q0⟩:\\n{cir_all.get_qs(ket=True, seed=seed)}\\n')\n",
    "\n",
    "\n",
    "simulate_fig8()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "cf96e9e9",
   "metadata": {},
   "source": [
    "### 案例5\n",
    "\n",
    "- Fig.9 实现量子路由机制的量子线路\n",
    "\n",
    "<img src=\"images/fig9.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "1263680c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fig.9\n",
      "complete circuit:\n",
      "q0: ──RX(1.84)────RY(4.272)────RZ(5.627)──────●────────H──────M(q0)──\n",
      "                                              │\n",
      "q1: ─────H────────────●───────────────────────X──────M(q1)───────────\n",
      "                      │\n",
      "q2: ──────────────────X────────────●──────────H──────M(q2)───────────\n",
      "                                   │\n",
      "q3: ─────H────────────●────────────X────────M(q3)────────────────────\n",
      "                      │\n",
      "q4: ──────────────────X────────────Z─────────────────────────────────\n",
      "\n",
      "Measure result:\n",
      "q3=1, q2=1, q1=1, q0=0\n",
      "\n",
      "Send state ¦qn,...,q0⟩:\n",
      "(0.5234607273332144-0.5317360554524077j)¦0⟩\n",
      "(-0.6215467966236228-0.23859005402281389j)¦1⟩\n",
      "\n",
      "Recv state ¦qn,...,q0⟩:\n",
      "(-0.5234607273332142+0.5317360554524074j)¦01110⟩\n",
      "(0.6215467966236227+0.23859005402281383j)¦11110⟩\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def simulate_fig9():\n",
    "    cir_send = create_random_state(0)\n",
    "    cir_epr12 = create_EPR_state(1, 2)\n",
    "    cir_epr34 = create_EPR_state(3, 4)\n",
    "    cir_mod01 = create_basic_module(0, 1)\n",
    "    cir_mod23 = create_basic_module(2, 3)\n",
    "\n",
    "    cir_all = cir_send + cir_epr12 + cir_epr34 + cir_mod01 + cir_mod23\n",
    "\n",
    "    # 使用同一个随机数种子，避免各次测量结果不同\n",
    "    seed = np.random.randint(0, 0xff) # 随机数种子\n",
    "\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q0-q3测量结果，保存在c0-c3\n",
    "    c0, c1, c2, c3 = get_measure_result(ket_str, [0, 1, 2, 3])\n",
    "    a1, a2, cc1, cc2 = c0, c1, c2, c3\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    if a2 != cc2: # XOR\n",
    "        cir_all += X(4)\n",
    "    if a1 != cc1: # XOR\n",
    "        cir_all += Z(4)\n",
    "\n",
    "    print(f'Fig.9\\ncomplete circuit:\\n{cir_all}\\n')\n",
    "    print(f'Measure result:\\nq3={c3}, q2={c2}, q1={c1}, q0={c0}\\n')\n",
    "    print(f'Send state ¦qn,...,q0⟩:\\n{cir_send.get_qs(ket=True, seed=seed)}\\n')\n",
    "    print(f'Recv state ¦qn,...,q0⟩:\\n{cir_all.get_qs(ket=True, seed=seed)}\\n')\n",
    "\n",
    "\n",
    "simulate_fig9()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "d2fdce3a",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "### 案例6\n",
    "\n",
    "- Fig.13 Alice和Bob在同一个QBK范围内的量子线路\n",
    "\n",
    "<img src=\"images/fig13.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "a6bd4a9b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fig.13\n",
      "complete circuit:\n",
      "q0: ──RX(3.658)────RY(4.457)────RZ(1.139)──────●────────H──────M(q0)──\n",
      "                                               │\n",
      "q1: ──────H────────────●───────────────────────X──────M(q1)───────────\n",
      "                       │\n",
      "q2: ───────────────────X────────────●──────────H──────M(q2)───────────\n",
      "                                    │\n",
      "q3: ──────H────────────●────────────X────────M(q3)────────────────────\n",
      "                       │\n",
      "q4: ───────────────────X──────────────────────────────────────────────\n",
      "\n",
      "Measure result:\n",
      "q3=0, q2=1, q1=0, q0=1\n",
      "\n",
      "Send state ¦qn,...,q0⟩:\n",
      "(0.5440831760500209+0.5600389380449433j)¦0⟩\n",
      "(-0.48900554532345786+0.3888488936022858j)¦1⟩\n",
      "\n",
      "Recv state ¦qn,...,q0⟩:\n",
      "(0.5440831760500209+0.5600389380449432j)¦00101⟩\n",
      "(-0.4890055453234578+0.38884889360228575j)¦10101⟩\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def simulate_fig13():\n",
    "    \"\"\"same to fig9\"\"\"\n",
    "    cir_send = create_random_state(0)\n",
    "    cir_epr12 = create_EPR_state(1, 2)\n",
    "    cir_epr34 = create_EPR_state(3, 4)\n",
    "    cir_mod01 = create_basic_module(0, 1)\n",
    "    cir_mod23 = create_basic_module(2, 3)\n",
    "\n",
    "    cir_all = cir_send + cir_epr12 + cir_epr34 + cir_mod01 + cir_mod23\n",
    "\n",
    "    # 使用同一个随机数种子，避免各次测量结果不同\n",
    "    seed = np.random.randint(0, 0xff)\n",
    "\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q0-q3测量结果，保存在c0-c3\n",
    "    c0, c1, c2, c3 = get_measure_result(ket_str, [0, 1, 2, 3])\n",
    "    a1, a2, cc1, cc2 = c0, c1, c2, c3\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    if a2 != cc2:  # XOR\n",
    "        cir_all += X(4)\n",
    "    if a1 != cc1:  # XOR\n",
    "        cir_all += Z(4)\n",
    "\n",
    "    print(f'Fig.13\\ncomplete circuit:\\n{cir_all}\\n')\n",
    "    print(f'Measure result:\\nq3={c3}, q2={c2}, q1={c1}, q0={c0}\\n')\n",
    "    print(f'Send state ¦qn,...,q0⟩:\\n{cir_send.get_qs(ket=True, seed=seed)}\\n')\n",
    "    print(f'Recv state ¦qn,...,q0⟩:\\n{cir_all.get_qs(ket=True, seed=seed)}\\n')\n",
    "\n",
    "\n",
    "simulate_fig13()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "cd2de444",
   "metadata": {},
   "source": [
    "### 案例7\n",
    "\n",
    "- Fig.14 Alice和Bob在不同QBK域内时的量子线路\n",
    "\n",
    "<img src=\"images/fig14.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "18e10f8b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fig.14\n",
      "complete circuit:\n",
      "q0: ──RX(2.044)────RY(0.348)────RZ(0.9)──────●────────H──────M(q0)──\n",
      "                                             │\n",
      "q1: ──────H────────────●─────────────────────X──────M(q1)───────────\n",
      "                       │\n",
      "q2: ───────────────────X───────────●─────────H──────M(q2)───────────\n",
      "                                   │\n",
      "q3: ──────H────────────●───────────X───────M(q3)────────────────────\n",
      "                       │\n",
      "q4: ───────────────────X───────────●─────────H──────M(q4)───────────\n",
      "                                   │\n",
      "q5: ──────H────────────●───────────X───────M(q5)────────────────────\n",
      "                       │\n",
      "q6: ───────────────────X────────────────────────────────────────────\n",
      "\n",
      "Measure result:\n",
      "q5=0, q4=0, q3=1, q2=0, q1=1, q0=0\n",
      "\n",
      "Send state ¦qn,...,q0⟩:\n",
      "(0.5268456231410298-0.09030861752018549j)¦0⟩\n",
      "(0.44685268089308594-0.7173567623974801j)¦1⟩\n",
      "\n",
      "Recv state ¦qn,...,q0⟩:\n",
      "(0.52684562314103-0.09030861752018553j)¦0001010⟩\n",
      "(0.44685268089308605-0.7173567623974798j)¦1001010⟩\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def simulate_fig14():\n",
    "    \"\"\"复现 Fig.14 线路\"\"\"\n",
    "    cir_send = create_random_state(0)  # the send state\n",
    "    cir_epr12 = create_EPR_state(1, 2)\n",
    "    cir_epr34 = create_EPR_state(3, 4)\n",
    "    cir_epr56 = create_EPR_state(5, 6)\n",
    "\n",
    "    cir_mod01 = create_basic_module(0, 1)\n",
    "    cir_mod23 = create_basic_module(2, 3)\n",
    "    cir_mod45 = create_basic_module(4, 5)\n",
    "\n",
    "    cir_all = cir_send + cir_epr12 + cir_epr34 + cir_epr56 +\\\n",
    "                cir_mod01 + cir_mod23 + cir_mod45\n",
    "\n",
    "    # 使用同一个随机数种子，避免各次测量结果不同\n",
    "    seed = np.random.randint(0, 0xff)\n",
    "\n",
    "    # get_qs 不会改变系统状态\n",
    "    ket_str = cir_all.get_qs(ket=True, seed=seed)\n",
    "    # 获取q0-q3测量结果，保存在c0-c3\n",
    "    c0, c1, c2, c3, c4, c5 = get_measure_result(ket_str, [0, 1, 2, 3, 4, 5])\n",
    "    # 根据测量结果判断是否加入 X 或 Z 门\n",
    "    i0, i1, i2, i3, i4, i5 = int(c0), int(c1), int(c2), \\\n",
    "                                int(c3), int(c4), int(c5)\n",
    "    if i1+i3+i5 in [1, 3]:  # XOR\n",
    "        cir_all += X(6)\n",
    "    if i0+i2+i4 in [1, 3]:  # XOR\n",
    "        cir_all += Z(6)\n",
    "\n",
    "    print(f'Fig.14\\ncomplete circuit:\\n{cir_all}\\n')\n",
    "    print(f'Measure result:\\nq5={c5}, q4={c4}, q3={c3}, q2={c2}, q1={c1}, q0={c0}\\n')\n",
    "    print(f'Send state ¦qn,...,q0⟩:\\n{cir_send.get_qs(ket=True, seed=seed)}\\n')\n",
    "    print(f'Recv state ¦qn,...,q0⟩:\\n{cir_all.get_qs(ket=True, seed=seed)}\\n')\n",
    "\n",
    "\n",
    "simulate_fig14()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.6"
  },
  "vscode": {
   "interpreter": {
    "hash": "9e29c145b53c9f4751736325a7cae7425ef0693c1192ca6a84dea59eaad784ff"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
